'use strict';
const { Model } = require('sequelize');
const bcrypt = require('bcryptjs');
const { BadRequest, Conflict } = require('http-errors');
module.exports = (sequelize, DataTypes) => {
  class User extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
      models.User.hasMany(models.Course, { as: 'courses' });
      models.User.belongsToMany(models.Course, {
        through: models.Like,
        foreignKey: 'userId',
        as: 'likeCourses',
      });
      models.User.hasMany(models.Attachment, { as: 'attachments' });
      models.User.hasMany(models.Order, { as: 'orders' });
    }
  }
  User.init(
    {
      email: {
        type: DataTypes.STRING,
        allowNull: false,
        validate: {
          notNull: {
            msg: '邮箱必须存在',
          },
          notEmpty: {
            msg: '邮箱不能为空',
          },
          isEmail: { msg: '邮箱格式不正确' },
          async isUnique(value) {
            const user = await User.findOne({ where: { email: value } });
            if (user) {
              throw new Conflict('邮箱已存在，请直接登录');
            }
          },
        },
      },
      username: {
        type: DataTypes.STRING,
        allowNull: false,
        validate: {
          notNull: {
            msg: '用户名必须存在',
          },
          notEmpty: {
            msg: '用户名不能为空',
          },
          len: { args: [2, 45], msg: '用户名长度必须在2~45之间' },
          async isUnique(value) {
            const user = await User.findOne({ where: { username: value } });
            if (user) {
              throw new Conflict('用户名已存在');
            }
          },
        },
      },
      password: {
        type: DataTypes.STRING,
        allowNull: false,
        validate: {
          notNull: {
            msg: '密码必须存在',
          },
          notEmpty: {
            msg: '密码不能为空',
          },
        },
        set(value) {
          if (value.length >= 6 && value.length <= 45) {
            this.setDataValue('password', bcrypt.hashSync(value, 10));
          } else {
            throw new BadRequest('密码长度必须是6~45之间');
          }
        },
      },
      nickname: DataTypes.STRING,
      sex: {
        type: DataTypes.TINYINT,
        allowNull: false,
        validate: {
          notNull: {
            msg: '性别必须存在',
          },
          notEmpty: {
            msg: '性别不能为空',
          },
          isIn: {
            args: [[0, 1, 2]],
            msg: '性别的值必须是，男0 女1 未选择2',
          },
        },
      },
      company: DataTypes.STRING,
      introduce: DataTypes.TEXT,
      role: {
        type: DataTypes.TINYINT,
        allowNull: false,
        validate: {
          notNull: {
            msg: '用户组必须存在',
          },
          notEmpty: {
            msg: '用户组不能为空',
          },
          isIn: {
            args: [[0, 1, 100]],
            msg: '用户组的值必须是，普通用户0 管理员100',
          },
        },
      },
      avatar: {
        type: DataTypes.STRING,
        validate: {
          isUrl: { msg: '图片地址不正确' },
        },
      },
      membershipExpiredAt: DataTypes.DATE,
      openid: DataTypes.STRING
    },
    {
      sequelize,
      modelName: 'User',
    }
  );
  return User;
};
